package com.mind.adjust.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.alibaba.excel.read.listener.ReadListener;
import com.mind.adjust.service.AjRuleService;
import com.mind.common.core.domain.AjaxResult;
import com.mind.common.log.annotation.Log;
import com.mind.common.log.enums.BusinessType;
import com.mind.common.utils.poi.ExcelUtil;
import com.mind.common.utils.poi.ImportExcelResult;
import com.mind.common.utils.poi.ValidationUtils;
import com.mind.common.web.controller.BaseController;
import com.mind.common.web.page.TableDataInfo;
import com.mind.system.domain.AjRule;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.ConstraintViolation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 智能审核模块/审核模块/规则配置管理
 *
 * @author makejava
 * @DocView.PathPrefix {{host}}/api/adjust
 * @since 2024-07-15 15:35:21
 */
@RestController
@RequestMapping("adjust/rule")
@Tag(name = "规则配置管理", description = "规则配置管理")
public class AjRuleController extends BaseController {
    /**
     * 服务对象
     */
    @Autowired
    private AjRuleService ajRuleService;

    /**
     * 获取规则配置列表
     *
     * @param rule 筛选条件
     * @return com.mind.system.domain.AjRule
     */
    @PreAuthorize("@ss.hasPermi('adjust:rule:list')")
    @Log(title = "规则配置列表", businessType = BusinessType.QUERY)
    @GetMapping("/list")
    @Operation(summary = "规则配置列表", description = "规则配置列表")
    public TableDataInfo list(AjRule rule) {
        startPage();
        List<AjRule> list = ajRuleService.selectRuleList(rule);
        return getDataTable(list);
    }

    /**
     * 规则配置导入
     *
     * @return 结果
     */
//    @RequiresPermissions("adjust:rule:import")
    @Log(title = "规则配置导入", businessType = BusinessType.IMPORT)
    @PostMapping("/import")
    @Operation(summary = "规则配置导入", description = "规则配置导入")
    public AjaxResult importExcel(MultipartFile file) throws IOException {
        List<AjRule> cachedDataList = new ArrayList<>();
        List<ImportExcelResult> errorList = new ArrayList<>();
        EasyExcel.read(file.getInputStream(), AjRule.class, new ReadListener<AjRule>() {

            @Override
            public void invoke(AjRule data, AnalysisContext context) {
                Set<ConstraintViolation<AjRule>> violations = ValidationUtils.getValidator().validate(data);
                if (violations.size() > 0) {
                    throw new ExcelDataConvertException(context.readRowHolder().getRowIndex(), 0, null, null, "");
                }
                cachedDataList.add(data);
            }

            @Override
            public void doAfterAllAnalysed(AnalysisContext context) {
                saveData();
            }

            /**
             * 加上存储数据库
             */
            private void saveData() {
                int i = ajRuleService.batchInsert(cachedDataList);
            }

            /**
             * 在转换异常 获取其他异常下会调用本接口。抛出异常则停止读取。如果这里不抛出异常则 继续读取下一行。
             *
             * @param exception
             * @param context
             * @throws Exception
             */
            @Override
            public void onException(Exception exception, AnalysisContext context) {
                // 如果是某一个单元格的转换异常 能获取到具体行号
                // 如果要获取头的信息 配合invokeHeadMap使用
                if (exception instanceof ExcelDataConvertException) {
                    ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException) exception;
                    String errMsg = String.format("第%d行数据验证异常", excelDataConvertException.getRowIndex());
                    errorList.add(new ImportExcelResult() {{
                        setRow(excelDataConvertException.getRowIndex());
                        setCol(excelDataConvertException.getColumnIndex());
                        setError(errMsg);
                    }});
                }
            }
        }).sheet().doRead();
        if (errorList.size() > 0) {
            return AjaxResult.success(String.format("一共%d条，成功导入%d条，错误%d条。错误详情：%s", cachedDataList.size() + errorList.size(), cachedDataList.size(), errorList.size(), errorList.stream().map(ImportExcelResult::getError).collect(Collectors.joining("\r\n"))));
        } else {
            return AjaxResult.success(String.format("一共%d条，成功导入%d条，错误0条。", (cachedDataList.size()), cachedDataList.size()));
        }
    }

    /**
     * 附件类型下载模板
     *
     * @return 结果
     */
    @Log(title = "规则配置下载模板", businessType = BusinessType.DOWNLOAD)
//    @RequiresPermissions("adjust:attachType:download")
    @GetMapping("/downloadTemplate")
    @Operation(summary = "规则配置下载模板", description = "规则配置下载模板")
    public void downloadTemplate(HttpServletResponse response) throws IOException {
        ExcelUtil<AjRule> util = new ExcelUtil<>(AjRule.class);
        String fileName = URLEncoder.encode("规则配置模板", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        util.exportExcel(response, new ArrayList<>(), "规则配置数据");
    }

    /**
     * 规则配置导出
     *
     * @param rule 筛选条件
     * @return 结果
     */
    @Log(title = "规则配置导出", businessType = BusinessType.EXPORT)
//    @RequiresPermissions("adjust:rule:export")
    @PostMapping("/export")
    @Operation(summary = "规则配置导出", description = "规则配置导出")
    public void export(HttpServletResponse response, AjRule rule) {
        List<AjRule> list = ajRuleService.selectRuleList(rule);
        ExcelUtil<AjRule> util = new ExcelUtil<AjRule>(AjRule.class);
        util.exportExcel(response, list, "规则配置数据");
    }

    /**
     * 根据ID获取规则配置详情
     *
     * @return com.mind.system.domain.AjRule
     */
//    @RequiresPermissions("adjust:rule:query")
    @GetMapping(value = "/{ruleId}")
    @Operation(summary = "获取规则配置详情", description = "获取规则配置详情")
    public AjaxResult getInfo(@Parameter(description = "规则Id", required = true) @PathVariable Long ruleId) {
        return success(ajRuleService.selectRuleById(ruleId));

    }

    @GetMapping(value = "/findByRuleId/{ruleId}")
    @Operation(summary = "获取规则配置详情", description = "获取规则配置详情")
    public AjaxResult findByRuleId(@Parameter(description = "规则Id", required = true) @PathVariable Long ruleId) {
        return success(ajRuleService.findByRuleId(ruleId));
    }

    /**
     * 新增规则配置
     *
     * @return 结果
     */
//    @RequiresPermissions("adjust:rule:add")
    @Log(title = "规则配置新增", businessType = BusinessType.INSERT)
    @PostMapping
    @Operation(summary = "规则配置新增", description = "规则配置新增")
    public AjaxResult add(@Validated @RequestBody AjRule rule) {
        int i = ajRuleService.insertRule(rule);
        if (i > 0) {
            return success(rule);
        }
        return error("新增失败");
    }

    /**
     * 修改规则配置
     *
     * @return 结果
     */
//    @RequiresPermissions("adjust:rule:edit")
    @Log(title = "规则配置修改", businessType = BusinessType.UPDATE)
    @PutMapping
    @Operation(summary = "规则配置修改", description = "规则配置修改")
    public AjaxResult edit(@Validated @RequestBody AjRule rule) {
        return toAjax(ajRuleService.updateRule(rule));
    }

    /**
     * 删除规则配置
     *
     * @return 结果
     */
    @PreAuthorize("@ss.hasPermi('adjust:rule:remove')")
    @Log(title = "规则配置删除", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ruleIds}")
    @Operation(summary = "规则配置删除", description = "规则配置删除")
    public AjaxResult remove(@Parameter(description = "规则Id", required = true) @PathVariable Long[] ruleIds) {
        return toAjax(ajRuleService.deleteRuleByIds(ruleIds));
    }


    /**
     * 修改状态
     *
     * @return 结果
     */
    //@RequiresPermissions("adjust:rule:edit")
    @Log(title = "修改规则配置状态", businessType = BusinessType.UPDATE)
    //@ApiOperation(value = "修改规则配置状态")
    @PutMapping("/editStatus")
    @Operation(summary = "修改规则配置状态", description = "修改规则配置状态")
    public AjaxResult editStatus(@Parameter(description = "规则Id", required = true) Long[] ruleIds, @Parameter(description = "状态", required = true) String status) {
        int count = 0;
        for (Long id : ruleIds) {
            count += ajRuleService.updateStatus(id, status);
        }
        return toAjax(count);
    }

    @Log(title = "修改规则配置状态", businessType = BusinessType.UPDATE)
    //@ApiOperation(value = "修改规则配置状态")
    @PutMapping("/exportBusiness")
    @Operation(summary = "修改规则配置状态", description = "修改规则配置状态")
    public void exportBusiness(HttpServletResponse response, AjRule rule) {
        List<AjRule> list = ajRuleService.selectRuleList(rule);
        ExcelUtil<AjRule> util = new ExcelUtil<AjRule>(AjRule.class);
        util.exportExcel(response, list, "规则配置数据");
    }

}


